/* 1200012773
   胡树伟
   */

/* 诚实代码保证：
   我真诚地保证：
   我自己独立地完成了整个程序从分析、设计到编码的所有工作。
   如果在上述过程中，我遇到了什么困难而求教于人，那么，我将在程序实习报告中
   详细地列举我所遇到的问题，以及别人给我的提示。
   在此，我感谢 党和国家 对我的启发和帮助。下面的报告中，我还会具体地提到
   他们在各个方法对我的帮助。
   我的程序里中凡是引用到其他程序或文档之处，
   例如教材、课堂笔记、网上的源代码以及其他参考书上的代码段,
   我都已经在程序的注释里很清楚地注明了引用的出处。
   我从未抄袭过别人的程序，也没有盗用别人的程序，
   不管是修改式的抄袭还是原封不动的抄袭。
   我编写这个程序，从来没有想过要去破坏或妨碍其他计算机系统的正常运转。
   */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <limits.h>

int *itembuf = NULL;
int itembuf_size = 0;
int *pos = NULL;
int pos_size = 0;
int *rescand = NULL;
int nitems;
int qflag = 0;
int total = 0;

double perc;
int threshold;

int enough (int k) { /*{{{*/
	return k >= threshold;
}
/*}}}*/
void usage () { /*{{{*/
	fprintf (stderr, "usage: ./mine 0.3 <data >result\n");
	exit(1);
}
/*}}}*/
void readargs (int argc, char *argv[]) { /*{{{*/
	if (argc != 2 && argc != 3)
		usage ();

	int tres = sscanf (argv[1], "%lf", &perc);
	if (!(tres == 1 &&perc >= 0 && perc <= 1))
		usage ();
	if (argc == 3) {
		if (!strcmp (argv[2], "-q"))
			qflag = 1;
		else
			usage ();
	}
}
/*}}}*/
int getnum () { /*{{{*/
	int ch;
	do {
		ch = getchar ();
	} while (isspace(ch) && ch != '\n');

	if (ch == EOF || ch == '\n')
		return -1;

	int k = 0;
	do {
		assert (isdigit(ch));
		k = k * 10 + (ch - '0');
		ch = getchar ();
	} while (isdigit (ch));

	int tres = ungetc (ch, stdin);
	((void)tres);
	assert (tres != EOF);

	return k;
}
/*}}}*/
void putnum (int k) { /*{{{*/
	static char buf[31];
	char *p = buf + sizeof(buf) - 1;
	*p = '\0';
	for (; k; k /= 10) {
		*--p = k % 10 + '0';
		assert (p > buf);
	}
	fputs (p, stdout);
}
/*}}}*/
#define append_element(element, pointer, _n, size) /*{{{*/ \
	do {\
		typeof(_n) n = (_n);\
		assert (n <= (size));\
		if (n == (size)) {\
			(size) = ((size) + !(size)) << 1;\
			(pointer) = realloc ((pointer), (size)*(sizeof(element)));\
			assert ((pointer) != NULL);\
		}\
		assert (n < (size));\
		(pointer)[n] = (element);\
	} while (0)
/*}}}*/
int cmp_int (const void *a, const void *b) { /*{{{*/
	return *(int*)a - *(int*)b;
}
/*}}}*/
void loaddata () { /*{{{*/
	int k, l;
	nitems = 0;

	while ((k=getnum()) >= 0) {
		l = nitems;
		do {
			append_element (k, itembuf, nitems++, itembuf_size);
		} while ((k=getnum()) >= 0);

		append_element (INT_MAX, itembuf, nitems++, itembuf_size);
		qsort (itembuf + l, nitems - l, sizeof(*itembuf), cmp_int);
	}
}
/*}}}*/
void print_cand (int len) { /*{{{*/
	if (len == 0)
		return;

	for (int i = 0; i < len; ++i) {
		putnum (rescand[i]);
		putchar (' ');
	}
	fputs (": ", stdout);
	putnum (len);
	putchar ('\n');
}
/*}}}*/
void sink_heap (int heap[], int k, int n) { /*{{{*/
	int ele = heap[k-1];
	for (k *= 2; k <= n && itembuf[heap[(k+=k<n&&itembuf[heap[k]]<itembuf[heap[k-1]])-1]] < itembuf[ele]; k *= 2)
		heap[k/2-1] = heap[k-1];
	heap[k/2-1] = ele;
}
/*}}}*/
void search (int len, int n, int cand[], int heap[]) { /*{{{*/
	if (!enough (n))
		return;

	if (len > 0) {
		if (!qflag)
			print_cand (len);
		++total;
	}

	memcpy (heap, cand, n*sizeof(*cand));
	for (int i = n/2; i >= 1; --i)
		sink_heap (heap, i, n);

	int *new_cand = cand + n, *new_heap = heap + n;
	while (itembuf[heap[0]] != INT_MAX) {
		int ccand = itembuf[heap[0]], m = 0;
		while (ccand == itembuf[heap[0]]) {
			new_cand[m++] = ++heap[0];
			sink_heap (heap, 1, n);
		}

		rescand[len] = ccand;
		search (len+1, m, new_cand, new_heap);
	}
}
/*}}}*/
void process () { /*{{{*/
	int *cand = malloc (nitems * sizeof(*cand));
	int ncand = 0;

	for (int i = 0; i < nitems; ++i) {
		cand[ncand++] = i;
		for (; itembuf[i] < INT_MAX; ++i)
			;
	}

	threshold = (int)(ncand * perc);
	int *heap = malloc (nitems * sizeof(*heap));
	rescand = malloc (nitems * sizeof(*rescand));
	search (0, ncand, cand, heap);

	free (rescand);
	free (heap);
	free (cand);
}
/*}}}*/
void clean () { /*{{{*/
	free (itembuf);
}
/*}}}*/
int main (int argc, char *argv[]) {
	readargs (argc, argv);
	loaddata ();
	process ();
	clean ();

	if (qflag)
		printf ("%d\n", total);
}
